﻿#include "SQLiteDB.h"
#include <iostream> // 用于打印错误信息和调试信息

// 构造函数：传入数据库文件路径，初始化连接池
SQLiteDB::SQLiteDB(const std::string& dbFile) : dbFile_(dbFile) {
    InitPool(); // 调用 InitPool 函数创建默认大小的连接池
}

// 析构函数：释放连接池中的所有数据库连接
SQLiteDB::~SQLiteDB() {
    while(!connPool_.empty()){
        sqlite3* db = connPool_.front(); // 取出队首连接
        connPool_.pop();                 // 从队列中移除
        sqlite3_close(db);               // 关闭 SQLite 连接
    }
}

// 初始化连接池
void SQLiteDB::InitPool() {
    for(int i = 0; i < poolSize_; i++){
        sqlite3* db;
        // 打开 SQLite 数据库文件，如果不存在则创建
        if(sqlite3_open(dbFile_.c_str(), &db) != SQLITE_OK){
            std::cerr << "Cannot open SQLite DB\n"; // 打开失败打印错误
        } else {
            connPool_.push(db); // 成功打开，加入连接池
        }
    }
}

// 获取一个可用数据库连接（从连接池取出）
sqlite3* SQLiteDB::GetConnection() {
    std::lock_guard<std::mutex> lock(poolMutex_); // 加锁保证线程安全
    if(connPool_.empty()) return nullptr;         // 如果池为空，返回 nullptr
    sqlite3* db = connPool_.front();              // 取出队首连接
    connPool_.pop();                              // 从队列中移除
    return db;                                    // 返回连接
}

// 释放连接（将连接放回连接池）
void SQLiteDB::ReleaseConnection(sqlite3* conn) {
    std::lock_guard<std::mutex> lock(poolMutex_); // 加锁保证线程安全
    connPool_.push(conn);                         // 将连接放回队列
}

// 执行不返回结果的 SQL 语句（如 CREATE、INSERT、UPDATE、DELETE）
bool SQLiteDB::Execute(const std::string& sql) {
    sqlite3* db = GetConnection(); // 从连接池获取一个连接
    if(!db) return false;          // 如果没有可用连接，返回 false

    char* errMsg = nullptr;        // 存储错误信息
    int rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errMsg); // 执行 SQL
    if(rc != SQLITE_OK) {          // 执行失败
        std::cerr << "SQLite Execute error: " << errMsg << std::endl; // 打印错误
        sqlite3_free(errMsg);      // 释放错误信息内存
        ReleaseConnection(db);     // 释放连接回连接池
        return false;              // 返回失败
    }

    ReleaseConnection(db);         // 执行成功，释放连接回连接池
    return true;                   // 返回成功
}

// 执行查询 SQL 语句（如 SELECT），通过回调处理结果
bool SQLiteDB::Query(const std::string& sql, int(*callback)(void*,int,char**,char**), void* data) {
    sqlite3* db = GetConnection(); // 从连接池获取一个连接
    if(!db) return false;          // 如果没有可用连接，返回 false

    char* errMsg = nullptr;        // 存储错误信息
    int rc = sqlite3_exec(db, sql.c_str(), callback, data, &errMsg); // 执行 SQL 并调用回调
    if(rc != SQLITE_OK){           // 执行失败
        std::cerr << "SQLite Query error: " << errMsg << std::endl;  // 打印错误
        sqlite3_free(errMsg);      // 释放错误信息内存
        ReleaseConnection(db);     // 释放连接回连接池
        return false;              // 返回失败
    }

    ReleaseConnection(db);         // 执行成功，释放连接回连接池
    return true;                   // 返回成功
}
